package com.bluebridgecup.BasicAlgorithms.BasicAlgorithmComprehensiveProblem;

import java.util.Scanner;

public class KMultipleIntervalCounter {
    public static void main(String[] args) {
        // 创建 Scanner 对象，用于从标准输入读取数据
        Scanner in = new Scanner(System.in);
        // 读取输入的整数 n，表示数组的长度
        int n = in.nextInt();
        // 读取输入的整数 k，用于判断区间和是否为 k 的倍数
        int k = in.nextInt();
        // 创建一个长度为 n 的整型数组 a，用于存储输入的数组元素
        int[] a = new int[n];
        // 创建一个长度为 200000 的长整型数组 b，用于记录每个余数出现的次数
        // 数组的索引表示余数，值表示该余数出现的次数
        long[] b = new long[200000];
        // 用于存储前缀和
        long sum = 0;
        // 用于记录满足 k 倍区间的数量
        long count = 0;

        // 循环读取数组 a 的元素，并计算前缀和
        for (int i = 0; i < n; i++) {
            // 读取数组 a 的第 i 个元素
            a[i] = in.nextInt();
            // 累加当前元素到前缀和 sum 中
            sum += a[i];
            // 计算当前前缀和 sum 对 k 取余的结果
            // 将该余数对应的数组 b 中的元素值加 1，表示该余数出现的次数增加 1
            // 这里利用取余操作将相同余数的前缀和情况统计在一起
            b[(int) (sum % k)]++;
        }

        // 余数为 0 的前缀和本身就构成一个 k 倍区间
        // 所以将余数为 0 的出现次数累加到结果 count 中
        count = count + b[0];

        // 遍历所有可能的余数（从 0 到 k - 1）
        for (int i = 0; i < k; i++) {
            // 对于余数相同的前缀和，任意两个前缀和相减得到的区间和一定是 k 的倍数
            // 这里计算从 b[i] 个相同余数的前缀和中选取 2 个的组合数
            // 组合数公式为 C(n, 2) = n * (n - 1) / 2，其中 n 为 b[i]
            // 将这些组合数累加到结果 count 中
            count += (b[i] * (b[i] - 1)) / 2;
        }

        // 输出满足 k 倍区间的数量
        System.out.println(count);
    }
}